SHED.tree.DWRTreeLoader = function(config){
    SHED.tree.DWRTreeLoader.superclass.constructor.call(this, config);
};

Ext.extend(SHED.tree.DWRTreeLoader, Ext.tree.TreeLoader, {
    /**
     * @cfg dwrCall
     */
    /**
     * @cfg params
     */
    /**
     * @cfg nodeMeta
     *
     * <pre>
     * id   string
     * text string
     * leaf string
     * </pre>
     */
    dwrCall: null,
    params: [],
    nodeMeta: null,
    // uiProviders : {},
    clearOnLoad: true,
    
    load: function(node, callback){
        if (this.clearOnLoad) {
            while (node.firstChild) {
                node.removeChild(node.firstChild);
            }
        }
        if (this.doPreload(node)) { // preloaded json children
            if (typeof callback == "function") {
                callback();
            }
        } else if (this.dwrCall) {
            this.requestData(node, callback);
        }
    },
    
    requestData: function(node, callback){
        if (this.fireEvent("beforeload", this, node, callback) !== false) {
            var delegate = this.handleResponse.createDelegate(this, [node, callback], 1);
            var callParams = this.params.length > 0 ? this.params.slice() : this.getParams(node);
            callParams.push(delegate);
            this.transId = true;
            this.dwrCall.apply(this, callParams);
        } else {
            if (typeof callback == "function") {
                callback();
            }
        }
    },
    
    getParams: function(node){
        if (node && node.id) {
            return [node.id];
        } else {
            return null;
        }
    },
    
    abort: function(){
        if (this.isLoading()) {
        }
    },
    
    createNode: function(attr){
        if (this.nodeMeta) {
            if (this.nodeMeta.id) {
                attr.id = attr[this.nodeMeta.id];
            }
            if (this.nodeMeta.text) {
                attr.text = attr[this.nodeMeta.text];
            }
            if (!attr.leaf) {
                attr.leaf = this.nodeMeta.leaf ? attr[this.nodeMeta.leaf] : null;
            }
        }
        if (this.baseAttrs) {
            Ext.applyIf(attr, this.baseAttrs);
        }
        if (this.applyLoader !== false) {
            attr.loader = this;
        }
        if (typeof attr.uiProvider == 'string') {
            attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
        }
        return (attr.leaf ? new Ext.tree.TreeNode(attr) : new Ext.tree.AsyncTreeNode(attr));
    },
    
    processResponse: function(response, node, callback){
        try {
            var o = response;
            node.beginUpdate();
            for (var i = 0, len = o.length; i < len; i++) {
                var r = o[i];
                if (r.children && r.children.length == 0) {
                    delete r.children;
                }
                var n = this.createNode(r);
                if (n) {
                    node.appendChild(n);
                }
            }
            node.endUpdate();
            if (typeof callback == "function") {
                callback(this, node);
            }
        } catch (e) {
            this.handleFailure(response, node, callback);
        }
    },
    
    handleResponse: function(response, node, callback){
        this.transId = false;
        this.processResponse(response, node, callback);
        this.fireEvent("load", this, node, {
            data: response,
            scope: this,
            argument: {
                callback: callback,
                node: node
            },
            params: this.getParams(node)
        });
    },
    
    handleFailure: function(response, node, callback){
        this.transId = false;
        this.fireEvent("loadexception", this, node, response);
        if (typeof callback == "function") {
            callback(this, node);
        }
    }
});
